package com.lemon.cloud.feign.config;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.lemon.cloud.comm.constants.CommonConstants;
import com.lemon.cloud.comm.constants.OAuth2Constant;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Optional;

/**
 * oauth2 feign token传递
 * <p>
 * 重新 OAuth2FeignRequestInterceptor
 *
 * @author HuangDS
 */
@Slf4j
public class OAuthRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        // 非web 请求直接跳过
        if (this.getRequest().isEmpty()) {
            return;
        }
        String s = MDC.get(CommonConstants.X_REQUEST_ID);
        Collection<String> requestIds = template.headers().get(CommonConstants.X_REQUEST_ID);
        if (CollUtil.isNotEmpty(requestIds)) {
            String traceId = requestIds.iterator().next();
            MDC.put(CommonConstants.X_REQUEST_ID,traceId);
        }
        // 内部调用想要授权 就不携带 FROM
        Collection<String> fromHeader = template.headers().get(OAuth2Constant.FROM);
        // 带from 请求直接跳过
        if (CollUtil.isNotEmpty(fromHeader) && fromHeader.contains(OAuth2Constant.FROM_IN)) {
            return;
        }
        HttpServletRequest request = this.getRequest().get();
        String authorizationHead = getAuthorizationHead(request);
        if (StrUtil.isNotEmpty(authorizationHead)) {
            template.header(HttpHeaders.AUTHORIZATION, authorizationHead);
        }
    }

    public String getAuthorizationHead(HttpServletRequest request) {
        return request.getHeader(HttpHeaders.AUTHORIZATION);
    }

    public Optional<HttpServletRequest> getRequest() {
        return Optional
                .ofNullable(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
    }
}
